package com.ruoyi.ruoyiqywechat.wx.pay.config;

import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;

/**
 * @author yhw
 * @date 2023/12/18
 * @apiNote 支付类（配置类） proxyBeanMethods = true 是配置类默认的，通过容器取Bean对象的时候总是返回同一个对象
 */
@Configuration
public class PayConfing {
    @Bean
    public CloseableHttpClient closeableHttpClient(){
        try {
            // 初始化证书管理器
            CertificatesManager certificatesManager = CertificatesManager.getInstance();
            PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(PayConstants.PRIVATE_KEY);
// 注册商户私钥和证书
            certificatesManager.putMerchant(PayConstants.MCH_ID, new WechatPay2Credentials(PayConstants.MCH_ID,
                            new PrivateKeySigner(PayConstants.MCH_SERIAL_NO, merchantPrivateKey)),
                    PayConstants.API_V3KEY.getBytes(StandardCharsets.UTF_8));

            return WechatPayHttpClientBuilder.create()
                    .withMerchant(PayConstants.MCH_ID, PayConstants.MCH_SERIAL_NO, merchantPrivateKey)
                    .withValidator(new WechatPay2Validator(certificatesManager.getVerifier(PayConstants.MCH_ID)))
                    .build();
        } catch (NotFoundException e) {
            throw new RuntimeException(e);
        } catch (GeneralSecurityException e) {
            throw new RuntimeException(e);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (HttpCodeException e) {
            throw new RuntimeException(e);
        }
    }
}
